//
//  NSImage+Thumbnail.m
//  photoSep
//
//  Created by David Michaeli on 05/10/12.
//  Copyright (c) 2012 David Michaeli. All rights reserved.
//

#import "NSImage+Thumbnail.h"

@implementation NSImage (Thumbnail)


- (NSImage*) thumbnailImageVertical: (int)vSize andHorizontal: (int)hSize {
    NSImage *sourceImage = [self copy];
    // Report an error if the source isn't a valid image
    if (![sourceImage isValid]) {
        NSLog(@"Invalid Image");
    }
    else {
        NSImage *smallImage = [[[NSImage alloc] initWithSize:NSMakeSize(hSize, vSize)] autorelease];
        [smallImage lockFocus];
        [sourceImage setSize:NSMakeSize(hSize, vSize)];
        [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
        [sourceImage compositeToPoint:NSZeroPoint operation:NSCompositeCopy];
        [smallImage unlockFocus];
        [sourceImage release];
        return smallImage;
    }
    return nil;
}

- (CGImageRef) createCGImage
{
    NSSize imageSize = [self size];
    
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, imageSize.width, imageSize.height, 8, 0, [[NSColorSpace genericRGBColorSpace] CGColorSpace], kCGBitmapByteOrder32Host|kCGImageAlphaPremultipliedFirst);
    
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:bitmapContext flipped:NO]];
    [self drawInRect:NSMakeRect(0, 0, imageSize.width, imageSize.height) fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
    [NSGraphicsContext restoreGraphicsState];
    
    CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext);
    CGContextRelease(bitmapContext);
    return cgImage;
}

-(CGImageRef)CGImage
{
    CGContextRef bitmapCtx = CGBitmapContextCreate(NULL/*data - pass NULL to let CG allocate the memory*/,
                                                   [self size].width,
                                                   [self size].height,
                                                   8 /*bitsPerComponent*/,
                                                   0 /*bytesPerRow - CG will calculate it for you if it's allocating the data.  This might get padded out a bit for better alignment*/,
                                                   [[NSColorSpace genericRGBColorSpace] CGColorSpace],
                                                   kCGBitmapByteOrder32Host|kCGImageAlphaPremultipliedFirst);
    
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:bitmapCtx flipped:NO]];
    [self drawInRect:NSMakeRect(0,0, [self size].width, [self size].height) fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
    [NSGraphicsContext restoreGraphicsState];
    
    CGImageRef cgImage = CGBitmapContextCreateImage(bitmapCtx);
    CGContextRelease(bitmapCtx);
    
    return cgImage;
}


+ (NSImage *)imageWithCVMat:(const CvMat)mat
{
    return [[[NSImage alloc] initWithCVMat:mat] autorelease];
}

- (id)initWithCVMat:(const CvMat)mat
{
    int elemSize = mat.step / mat.cols;
    NSData *data = [NSData dataWithBytes:mat.data.ptr length:mat.step*mat.rows];
    
    CGColorSpaceRef colorSpace;
    
    if (elemSize == 1)
    {
        colorSpace = CGColorSpaceCreateDeviceGray();
    }
    else
    {
        colorSpace = CGColorSpaceCreateDeviceRGB();
    }
    
    CGDataProviderRef provider = CGDataProviderCreateWithCFData(( CFDataRef)data);
    
    CGImageRef imageRef = CGImageCreate(mat.cols,                                       // Width
                                        mat.rows,                                       // Height
                                        8,                                              // Bits per component
                                        8 * elemSize,                                   // Bits per pixel
                                        mat.step,                                       // Bytes per row
                                        colorSpace,                                     // Colorspace
                                        kCGImageAlphaNone | kCGBitmapByteOrderDefault,  // Bitmap info flags
                                        provider,                                       // CGDataProviderRef
                                        NULL,                                           // Decode
                                        false,                                          // Should interpolate
                                        kCGRenderingIntentDefault);                     // Intent
    
    
    NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage:imageRef];
    NSImage *image = [[NSImage alloc] init];
    [image addRepresentation:bitmapRep];
    
    CGImageRelease(imageRef);
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorSpace);
    
    return image;
}

@end
